import FreeCAD
import numpy as np
import math
from .util.meshBoundary import MeshBoundary
#import pyrender
#import trimesh

def getNumpyMatrixFromMatrix(matrix):
    return np.array(matrix.A).reshape((4,4))

def _list3_min(l_a, l_b):
    return [min((a, b)) for (a, b) in zip(l_a if l_a else l_b, l_b)]


def _list3_max(l_a, l_b):
    return [max((a, b)) for (a, b) in zip(l_a if l_a else l_b, l_b)]

def getColorHash(color):
    return "{:.4f}".format(color[0]) + "{:.4f}".format(color[1]) \
        + "{:.4f}".format(color[2]) + "{:.4f}".format(color[3])



def getVisualize(shape, precision = 1, globalMatrix = FreeCAD.Matrix()):
    vets = []
    nors = []
    indices = []
    vetsGroup = []
    curIndex = 0
    faceCount = 0
    indicesGroup = []
    faceType = []
    faceMeta = []
    edgeVets = []
    edgeGroup = []
    edgeType = []
    edgeMeta = []

    globalMatrixInv = globalMatrix.inverse()
    globalMatrixInvRotate = FreeCAD.Matrix(globalMatrixInv)

    globalMatrixInvRotate.A14 = 0
    globalMatrixInvRotate.A24 = 0
    globalMatrixInvRotate.A34 = 0

    for face in shape.Faces:
        faceTess = face.tessellate(precision, 0.5)
        surface = face.Surface
        
        for v in faceTess[0]:
            vets.append(globalMatrixInv.multVec(v))
            uv = surface.parameter(v)
            # print('uv:', uv, faceCount)
            try:
                normal = surface.normal(*uv)
            except Exception as err:
                normal = FreeCAD.Vector(0,0,0)

            if(face.Orientation == 'Reversed'):
                normal = -1 * normal
            nors.append(globalMatrixInvRotate.multVec(normal))

        vCount = len(faceTess[0])
        vetsGroup.append(vCount)

        for unit in faceTess[1]:
            tri = []
            for i in unit:
                tri.append(i + curIndex)
            indices.append(tri)

        indicesGroup.append(len(faceTess[1]) * 3)
        curIndex += vCount
        faceCount += 1

        surfaceType = type(surface).__name__
        if(surfaceType == 'Plane'):
            faceType.append(1)
            position = globalMatrixInv.multVec(surface.Position)
            normal = globalMatrixInvRotate.multVec(face.normalAt(0,0))
            faceMeta.append(position.x)
            faceMeta.append(position.y)
            faceMeta.append(position.z)
            faceMeta.append(normal.x)
            faceMeta.append(normal.y)
            faceMeta.append(normal.z)
        elif(surfaceType == 'Cylinder'):
            position = globalMatrixInv.multVec(surface.Center)
            axis = globalMatrixInvRotate.multVec(surface.Axis)
            radius = surface.Radius
            faceType.append(2)
            faceMeta.append(position.x)
            faceMeta.append(position.y)
            faceMeta.append(position.z)
            faceMeta.append(axis.x)
            faceMeta.append(axis.y)
            faceMeta.append(axis.z)
            faceMeta.append(radius)
        elif(surfaceType == 'Sphere'):
            position = globalMatrixInv.multVec(surface.Center)
            radius = surface.Radius
            faceType.append(3)
            faceMeta.append(position.x)
            faceMeta.append(position.y)
            faceMeta.append(position.z)
            faceMeta.append(radius)
        else:
            faceType.append(0)

    for edge in shape.Edges:
        if(edge.Degenerated):
            continue
        dis = edge.discretize(Deflection = 0.04)
        for v in dis:
            edgeVets.append(globalMatrixInv.multVec(v))
        edgeGroup.append(len(dis))

        curve = edge.Curve

        curveType = type(curve).__name__
        if(curveType == 'Line'):
            edgeType.append(1)
            position = globalMatrixInv.multVec(curve.Location)
            axis = globalMatrixInvRotate.multVec(curve.Direction)
            edgeMeta.append(position.x)
            edgeMeta.append(position.y)
            edgeMeta.append(position.z)
            edgeMeta.append(axis.x)
            edgeMeta.append(axis.y)
            edgeMeta.append(axis.z)
        elif(curveType == 'Circle'):
            edgeType.append(2)
            position = globalMatrixInv.multVec(curve.Center)
            axis = globalMatrixInvRotate.multVec(curve.Axis)
            radius = curve.Radius
            edgeMeta.append(position.x)
            edgeMeta.append(position.y)
            edgeMeta.append(position.z)
            edgeMeta.append(axis.x)
            edgeMeta.append(axis.y)
            edgeMeta.append(axis.z)
            edgeMeta.append(radius)
        else:
            edgeType.append(0)

    return (vets, nors, indices, vetsGroup, indicesGroup, edgeVets, edgeGroup, faceType, faceMeta, edgeType, edgeMeta)







class ToMergeObject:
    DEFAULT_COLOR = [round(val / 255., 4) for val in (244,244,244)] + [1.0]
    def __init__(self, obj):
        self.objs = [obj]
        self.level = obj.level
        self.faceVetNum = len(obj.tess[0])
        self.edgeVetNum = len(obj.wireDis)
        self.colorIndexDict = {}
        self.colorValueDict = {}
        self.centers = [obj.transformedBox.Center]
        self.distances = [self.getLimitDistance(obj.transformedBox)]


    def getLimitDistance(self, box):
        return box.DiagonalLength * 15


    def setColor(self, color, index):
        hashColor = getColorHash(color)
        if(hashColor in self.colorIndexDict):
            self.colorIndexDict[hashColor].append(index)
        else:
            self.colorIndexDict[hashColor] = [index]
            self.colorValueDict[hashColor] = color

    def tryMerge(self, obj, maxVertices):
        if(obj.level != self.level):
            return False
        faceVetNum = len(obj.tess[0]) 
        edgeVetNum = len(obj.wireDis)
        if(faceVetNum + self.faceVetNum > maxVertices):
            return False
        if(edgeVetNum + self.edgeVetNum > maxVertices):
            return False
        self.objs.append(obj)
        self.faceVetNum += faceVetNum
        self.edgeVetNum += edgeVetNum


        self.centers.append(obj.transformedBox.Center)
        self.distances.append(self.getLimitDistance(obj.transformedBox))
        return True

    def merge(self):
        #return {
        #   'face': {
        #       vertices,
        #       normals,
        #       indices,
        #       indicesGroup,
        #       colors,
        #       colorsGroup,
        #       merge,
        #    },
        #    'line': {
        #       vertices,
        #       verticesGroup,
        #       merge
        #    },
        #    'point': {
        #       vertices,
        #       verticesGroup,
        #       merge
        #    },
        #   'centers', #optional
        #   'distances', #optional
        #   'level',
        #   'names',
        #   'volume'
        #}
        result = {\
            'face':{\
                'merge':[],\
                'vertices': [],\
                'normals': [], \
                'indices': [],\
                'verticesGroup': [],\
                'colors': [], \
                'colorsGroup':[], \
                'indicesGroup': []\
            },\
            'line':{\
                'vertices': [],\
                'verticesGroup': [],\
                'merge':[]\
            },\
            'point':{\
                'vertices': [],\
                'merge': []\
            },\
            'level': self.level,\
            'centers': [],\
            'distances': [],\
            'names': [],\
            'volume': 0
        }
        indicesOffset = 0
        colorsOffset = 0
        for obj in self.objs:
            result['face']['merge'].append(len(obj.tess[4]))
            result['face']['vertices'].extend(obj.tess[0])
            result['face']['normals'].extend(obj.tess[1])
            result['face']['verticesGroup'].extend(obj.tess[3])
            newIndices = []
            for index in obj.tess[2]:
                newIndices.append((index[0] + indicesOffset, index[1] + indicesOffset, \
                    index[2] + indicesOffset))
            result['face']['indices'].extend(newIndices)
            result['face']['indicesGroup'].extend(obj.tess[4])
            for colorIndex in range(len(obj.tess[4])):
                colorValue = self.DEFAULT_COLOR
                if (obj.tess[5]):
                    if(len(obj.tess[5]) == 1):
                        colorValue = obj.tess[5][0]
                    else:
                        colorValue = obj.tess[5][colorIndex]
                self.setColor(colorValue ,colorsOffset + colorIndex)
            colorsOffset += len(obj.tess[4])

            #result['face']['colors'].extend(obj.tess[5])
            indicesOffset += len(obj.tess[0])

            result['line']['merge'].append(len(obj.wireGroup))
            result['line']['vertices'].extend(obj.wireDis)
            result['line']['verticesGroup'].extend(obj.wireGroup)

            result['point']['vertices'].extend(obj.points)
            result['point']['merge'].append(len(obj.points))

            result['names'].append(obj.name)

            if(obj.volume > result['volume']):
                result['volume'] = obj.volume
            obj.tess = ()
            obj.wireDis = []
            obj.points = []
            obj.wireGroup = [] 
        #handle colors
        colorsGroup = np.empty(colorsOffset, dtype = int)
        count = 0
        for (key, value) in self.colorIndexDict.items():
            result['face']['colors'].append(self.colorValueDict[key])
            for i in range(len(value)):
                colorsGroup[value[i]] = count
            count += 1
        result['face']['colorsGroup'] = colorsGroup
        result['centers'] = self.centers
        result['distances'] = self.distances

        return result
            
 

class ViewObject:
    BASE_TOLERANCE = 1.0
    LEVEL_BOUNDARY = 1.0/64
    VERTICES_NUM_MAX = 10000
    DEFAULT_COLOR = [round(val / 255., 4) for val in (244,244,244)] + [1.0]
    #colors: dict{obj.Name: [(r,g,b,t), ....]}
    def __init__(self, obj, colors = None, parentMatrix = None, info = {}, currentOrder = 0, up = []):
        self.up = up
        self.currentOrder = currentOrder


        if(isinstance(obj, list)):
            self.children = obj
            self.name = '__root__'
            self.localMatrix = FreeCAD.Matrix()
            self.parentMatrix = FreeCAD.Matrix()
            self.globalMatrix = FreeCAD.Matrix()
        else:
            self.colorInfos = colors
            self.tess = None
            self.wireDis = None
            self.colors = None
            if colors and obj.Name in colors:
                self.colors = colors[obj.Name]
            #self.tolerance = tolerance
            self.obj = obj
            self.localMatrix = obj.Placement.toMatrix()
            self.parentMatrix = FreeCAD.Matrix() if parentMatrix == None else parentMatrix
            self.globalMatrix = self.parentMatrix.multiply(self.localMatrix)
            #print('localMatrix:', self.localMatrix)
            self.children = []
            self.name = obj.Label
            #self.parse()
            self.preParse(info)

        self.inStructure = self.getOriginInStructure()
        



    def getOriginInStructure(self):
        result = ''
        for i in self.up:
            result += str(i) + '-'
        result += str(self.currentOrder)
        return result


    def preParse(self, info):

        if hasattr(self.obj, 'Group'):
            currentOrder = 0
            cpUp = self.up.copy()
            cpUp.append(self.currentOrder)
            for o in self.obj.Group:
                v = ViewObject(o, self.colorInfos, self.globalMatrix, info = info, currentOrder = currentOrder, up = cpUp)
                self.children.append(v)
                currentOrder += 1
        elif hasattr(self.obj, 'Shape' ):
            info['shapeNum']  += 1
            try:
                (vets, nors, indices, vetsGroup, indicesGroup, \
                    edgeVets, edgeGroup, faceType, faceMeta,\
                    edgeType, edgeMeta) = self.obj.Shape.visualize(100)
            except Exception as err:
#                print('currentOrder:', self.currentOrder)
#                print('currentOrder:', self.globalMatrix)
#                print('parentMatrix:', self.parentMatrix)
#                print('localMatrix:', self.localMatrix)
                (vets, nors, indices, vetsGroup, indicesGroup, \
                    edgeVets, edgeGroup, faceType, faceMeta,\
                    edgeType, edgeMeta) = getVisualize(self.obj.Shape, 100, self.globalMatrix)


#            print('vets:', vets)
#            print('nors:', nors)
#            print('indices:', indices)
#            print('vetsGroup:', vetsGroup)
#            print('indicesGroup:', indicesGroup)
#            print('edgeVets:', edgeVets)
#            print('edgeGroup:', edgeGroup)
#            print('faceType:', faceType)
#            print('faceMeta:', faceMeta)
#            print('edgeType:', edgeType)
#            print('edgeMeta:', edgeMeta)












            self.preTessVetsNum = len(vets)
            cMin = None
            cMax = None

            if(len(vets) > 0):
                for v in vets:
                    curV = self.parentMatrix.multiply(v)
                    cMin = _list3_min(cMin, (curV.x, curV.y, curV.z))
                    cMax = _list3_max(cMax, (curV.x, curV.y, curV.z))
            
            #print('cMin:', cMin, 'cMax:', cMax)
            #transformedBox = self.obj.Shape.BoundBox.transformed(self.parentMatrix)
            #self.volume = transformedBox.XLength * transformedBox.YLength * transformedBox.ZLength
                self.volume = (cMax[0] - cMin[0] ) * (cMax[1] - cMin[1]) * (cMax[2] - cMin[2])
            else:
                self.volume = 0
                cMin = [0,0,0]
                cMax = [0,0,0]

            self.cMin = cMin
            self.cMax = cMax
            info['scene_min'] = _list3_min(
                info['scene_min'],
                cMin
            )

            #print('transformedBox:', transformedBox)
            #info['scene_min'] = _list3_min(info['scene_min'], 
            #(transformedBox.XMin, transformedBox.YMin, transformedBox.ZMin))

            #info['scene_max'] = _list3_max(info['scene_max'],
            #(transformedBox.XMax, transformedBox.YMax, transformedBox.ZMax))

            info['scene_max'] = _list3_max(
                info['scene_max'],
                cMax
            )

            #self.transformedBox = transformedBox
            self.transformedBox = FreeCAD.BoundBox(cMin[0], cMin[1], cMin[2], 
                cMax[0], cMax[1], cMax[2])

            if(self.volume > info['maxVolume']):
                info['maxVolume'] = self.volume


    def getSuitableTolerance(self, maxVolume, total):
        

        box = self.obj.Shape.BoundBox
        #print(self.obj)
        if(self.volume == 0):
            self.level = 2
            return 10
        self.level = 0
        if(self.volume <  maxVolume * self.LEVEL_BOUNDARY * self.LEVEL_BOUNDARY):
            self.level = 2
        elif (self.volume < maxVolume * self.LEVEL_BOUNDARY):
            self.level = 1

        k = 30
        if(total > 2000):
            k = 10
        elif(total > 500):
            k = 5

        #if(self.preTessVetsNum > 10000):
        #    k *0.5


        if(self.level == 0):
            tolerance = (self.cMax[0] - self.cMin[0] + \
                self.cMax[1] - self.cMin[1] + self.cMax[2] - self.cMin[2])/k
            #print('tolerance0:', tolerance, k)
        elif(self.level == 1):
            tolerance = (self.cMax[0] - self.cMin[0] + \
                self.cMax[1] - self.cMin[1] + self.cMax[2] - self.cMin[2])/k * 2
            #print('tolerance1:', tolerance, k)
        else:
            tolerance = (self.BASE_TOLERANCE * maxVolume/self.volume) / 10
            tolerance = math.pow(tolerance, 1/2)
            #if(tolerance > 10):
            #    tolerance = 10
        #print('level:', self.level)
            #print('tolerance2:', tolerance)
        #tolerance = 1
        return  tolerance * 0.1;
        #if(tolerance > 100):
            

    def mergeShapes(self, info = {}):
        def volumeSort(e):
            return e.volume
        #if hasattr(self.obj, 'Group'):
        if (len(self.children) > 0):
            myShapes = []
            for child in self.children:
                if hasattr(child.obj, 'Group'):
                    child.mergeShapes(info)
                else:
                    myShapes.append(child)
            #sort them depends on volume
            myShapes.sort(key = volumeSort, reverse=True)
            toMerge = []
            for shapeObj in myShapes:
                flag = False
                for merge in toMerge:
                    if(merge.tryMerge(shapeObj, self.VERTICES_NUM_MAX)):
                        flag = True
                        break
                if not (flag):
                    toMerge.append(ToMergeObject(shapeObj))
            self.merged = []
            for obj in toMerge:
                self.merged.append(obj.merge())
            info['mergedNum'] += len(self.merged)



    def parse(self, info):
        if hasattr(self.obj, 'Group'):
            for child in self.children:
                child.parse(info)
        elif hasattr(self.obj, 'Shape' ):
            colors = self.colors
            faces = self.obj.Shape.Faces
            vets = []
            nors = []
            indices = []
            vetsGroup = []
            indicesGroup = []
            num = 0
            self.wireDis = []
            try:
                #if(self.obj.Shape.ShapeType == 'Shell'):
                #    (vets, nors, indices, vetsGroup, indicesGroup, \
                #        edgeVets, edgeGroup, faceType, faceMeta,\
                #        edgeType, edgeMeta) = getVisualize(self.obj.Shape, \
                #        self.getSuitableTolerance(info['maxVolume'], info['shapeNum']))
                #else:
                (vets, nors, indices, vetsGroup, indicesGroup, \
                    edgeVets, edgeGroup, faceType, faceMeta,\
                    edgeType, edgeMeta) = self.obj.Shape.visualize(\
                    self.getSuitableTolerance(info['maxVolume'], info['shapeNum']))
            except Exception as err:
                (vets, nors, indices, vetsGroup, indicesGroup, \
                    edgeVets, edgeGroup, faceType, faceMeta,\
                    edgeType, edgeMeta) = getVisualize(self.obj.Shape, \
                    self.getSuitableTolerance(info['maxVolume'], info['shapeNum']), self.globalMatrix)


            colorIndices = []
            #to make sure every face has a independency value
            #colors = None
            if not (self.colors):
                colors = [self.DEFAULT_COLOR]
                for g in indicesGroup:
                    colorIndices.append(0)
                #    colors.append(self.DEFAULT_COLOR)
            elif(len(self.colors) == 1):
            #    oneColor = self.colors[0]
            #    colors = []
                for g in indicesGroup:
                    colorIndices.append(0)
            else:
                #colors = self.colors
                colorIndexDict = {}
                colors = []
                #colorValueDict = {}
                for color in self.colors:
                    hashColor = getColorHash(color)
                    if(hashColor in colorIndexDict):
                        #colorIndexDict[hashColor].append(index)
                        colorIndices.append(colorIndexDict[hashColor])
                    else:
                        colorIndexDict[hashColor] = len(colors)
                        colorIndices.append(len(colors))
                        colors.append(color)
                        #colorValueDict[hashColor] = color
                
            #print('vets:', vets)
            #print('nors:', nors)
            #print('indices:', indices[:100])
            #print('vetsGroup:', vetsGroup)
            #print('indicesGroup:', indicesGroup)
            #print('edgeVets:', edgeVets)
            #print('edgeGroup:', edgeGroup, len(edgeGroup))
            #print('faceType:', faceType)
            #print('faceMeta:', faceMeta)
            #print('edgeType:', edgeType, len(edgeType))
            #print('edgeMeta:', edgeMeta)
            #print('colors:', colors)
            #print('colorIndices:', colorIndices)

            offset = 0
            self.wireDis = []
            self.wireGroup = []
            
            #startEndList = [] #edge order test
            #totalStartEndList = []
            #for edge in self.obj.Shape.Edges:
            #    vertexes = edge.Vertexes
            #    if(len(vertexes) > 0):
            #        totalStartEndUnit = []
            #        totalStartEndUnit.append(vertexes[0].Point)
            #        totalStartEndUnit.append(vertexes[len(vertexes) - 1].Point)
            #        totalStartEndUnit.append(edge.Orientation)
            #        totalStartEndList.append(totalStartEndUnit)


            for g in edgeGroup:
                edgeVets1 = []
             #   if(g > 0):
             #       startEndUnit = []  #edge order test
             #       startEndUnit.append(edgeVets[offset]) #edge order test
             #       startEndUnit.append(edgeVets[offset + g - 1]) #edge order test
             #       startEndList.append(startEndUnit)   #edge order test
             #   else:
             #       startEndList.append([])
                for i in range(g):
                    if i < g - 1:
                        edgeVets1.append(edgeVets[offset + i])
                        edgeVets1.append(edgeVets[offset + i + 1])
                    else:
                        break
                offset += g
                self.wireGroup.append(len(edgeVets1))
                self.wireDis.extend(edgeVets1)
            self.tess = (vets, nors, indices, vetsGroup, indicesGroup, colors, colorIndices)
            info['verticesNum'] += len(vets)
            pVets = []

            globalMatrixInv = self.globalMatrix.inverse()

            globalMatrixInvRotate = FreeCAD.Matrix(globalMatrixInv)
        
            globalMatrixInvRotate.A14 = 0
            globalMatrixInvRotate.A24 = 0
            globalMatrixInvRotate.A34 = 0

            for w in self.obj.Shape.Vertexes:
                p1 = globalMatrixInv.multVec(w.Point)
                pVets.append(p1)
            self.points = pVets

            newFaceMeta = []
            newEdgeMeta = []

            count = 0
            for ft in faceType:
                if(ft == 1):
                    pos = FreeCAD.Vector(faceMeta[count], faceMeta[count + 1], faceMeta[count + 2])
                    pos = globalMatrixInv.multVec(pos)
                    nor = FreeCAD.Vector(faceMeta[count + 3], faceMeta[count + 4], faceMeta[count + 5]) 
                    nor = globalMatrixInvRotate.multVec(nor)
                    newFaceMeta.append(pos.x)
                    newFaceMeta.append(pos.y)
                    newFaceMeta.append(pos.z)
                    newFaceMeta.append(nor.x)
                    newFaceMeta.append(nor.y)
                    newFaceMeta.append(nor.z)
                    count += 6
                elif(ft == 2):
                    pos = FreeCAD.Vector(faceMeta[count], faceMeta[count + 1], faceMeta[count + 2]) 
                    pos = globalMatrixInv.multVec(pos)
                    nor = FreeCAD.Vector(faceMeta[count + 3], faceMeta[count + 4], faceMeta[count + 5])
                    nor = globalMatrixInvRotate.multVec(nor)
                    r = faceMeta[count + 6]
                    newFaceMeta.append(pos.x)
                    newFaceMeta.append(pos.y)
                    newFaceMeta.append(pos.z)
                    newFaceMeta.append(nor.x)
                    newFaceMeta.append(nor.y)
                    newFaceMeta.append(nor.z)
                    newFaceMeta.append(r)
                    count += 7
                elif(ft == 3):
                    pos = FreeCAD.Vector(faceMeta[count], faceMeta[count + 1], faceMeta[count + 2]) 
                    pos = globalMatrixInv.multVec(pos)
                    r = faceMeta[count + 3]
                    newFaceMeta.append(pos.x)
                    newFaceMeta.append(pos.y)
                    newFaceMeta.append(pos.z)
                    newFaceMeta.append(r)
                    count += 4
                elif(ft == 4):
                    pos = FreeCAD.Vector(faceMeta[count], faceMeta[count + 1], faceMeta[count + 2]) 
                    pos = globalMatrixInv.multVec(pos)
                    nor = FreeCAD.Vector(faceMeta[count + 3], faceMeta[count + 4], faceMeta[count + 5])
                    nor = globalMatrixInvRotate.multVec(nor)
                    r = faceMeta[count + 6]
                    newFaceMeta.append(pos.x)
                    newFaceMeta.append(pos.y)
                    newFaceMeta.append(pos.z)
                    newFaceMeta.append(nor.x)
                    newFaceMeta.append(nor.y)
                    newFaceMeta.append(nor.z)
                    newFaceMeta.append(r)
                    count += 7

            count = 0
            for gt in edgeType:
                if(gt == 1):
                    pos = FreeCAD.Vector(edgeMeta[count], edgeMeta[count + 1], edgeMeta[count + 2])
                    pos = globalMatrixInv.multVec(pos)
                    nor = FreeCAD.Vector(edgeMeta[count + 3], edgeMeta[count + 4], edgeMeta[count + 5]) 
                    nor = globalMatrixInvRotate.multVec(nor)
                    newEdgeMeta.append(pos.x)
                    newEdgeMeta.append(pos.y)
                    newEdgeMeta.append(pos.z)
                    newEdgeMeta.append(nor.x)
                    newEdgeMeta.append(nor.y)
                    newEdgeMeta.append(nor.z)
                    count += 6
                elif(gt == 2):
                    pos = FreeCAD.Vector(edgeMeta[count], edgeMeta[count + 1], edgeMeta[count + 2]) 
                    pos = globalMatrixInv.multVec(pos)
                    nor = FreeCAD.Vector(edgeMeta[count + 3], edgeMeta[count + 4], edgeMeta[count + 5])
                    nor = globalMatrixInvRotate.multVec(nor)
                    r = edgeMeta[count + 6]
                    newEdgeMeta.append(pos.x)
                    newEdgeMeta.append(pos.y)
                    newEdgeMeta.append(pos.z)
                    newEdgeMeta.append(nor.x)
                    newEdgeMeta.append(nor.y)
                    newEdgeMeta.append(nor.z)
                    newEdgeMeta.append(r)
                    count += 7



                    #count += 1


            self.geom = (faceType, newFaceMeta, edgeType, newEdgeMeta)
            #check edge orders
            #def checkEqualVector(v0, v1):
            #    return math.fabs(v0.x - v1.x) < 1e-3 and math.fabs(v0.y - v1.y) < 1e-3 and math.fabs(v0.z - v1.z) < 1e-3

            #if(len(startEndList) != len(totalStartEndList)):
            #    print('edge order check failed: they have difference length')
            #    print('length of startEndList:', len(startEndList))
            #    print('length of totalStartEndList', len(totalStartEndList))
            #    print('startEndList:', startEndList)
            #    print('totalStartEndList', totalStartEndList)
            #else:
            #    flag = True
            #    for i in range(len(startEndList)):
            #        startEndUnit0 = startEndList[i]
            #        startEndUnit1 = totalStartEndList[i]
            #        if(len(startEndUnit0) == 0):
            #            break


            #        if not checkEqualVector(startEndUnit0[0], startEndUnit1[0]):
            #            if not checkEqualVector(startEndUnit0[0], startEndUnit1[1]):
            #                print('edge order check failed: difference value on start point of:', i, startEndUnit0[0], startEndUnit1[0], startEndUnit1[2])
            #                flag = False
            #            elif not checkEqualVector(startEndUnit0[1], startEndUnit1[0]):
            #                print('edge order check failed: difference value on start point of:', i, startEndUnit0[0], startEndUnit1[0], startEndUnit1[2])
            #                flag = False
            #        elif not (checkEqualVector(startEndUnit0[1], startEndUnit1[1])):
            #            print('edge order check failed: difference value on end point of:', i, startEndUnit0[1], startEndUnit1[1], startEndUnit1[2])
            #            flag = False
            #    if(flag):
            #        print('edge order check succeeded!')

                    

    def renderPrimitive(self):
        primitives = []
        if hasattr(self.obj, 'Shape'):
            pose = getNumpyMatrixFromMatrix(self.parentMatrix)
            tess = self.tess
            wireDis = self.wireDis
            (vertices, indices, vetsGroup, indicesGroup, colors) = tess
            offset = 0
            i_offset = 0
            if tess and len(tess[0]) > 0:
                for i in range(len(vetsGroup)):
                    vg = vetsGroup[i]
                    ig = indicesGroup[i]
                    c_vets = tess[0][offset: offset+vg]
                    c_indices = indices[i_offset: int(i_offset+ig/3)]
                    offset += vg
                    i_offset += int(ig/3)
                    c_vets_array = []
                    c_color_array = []
                    #mat = pyrender.MetallicRoughnessMaterial()
                    for v in c_vets:
                        c_vets_array.append((v.x, v.y, v.z))
                        if(colors):
                            mat.baseColorFactor = (*colors[i][0:3], 1.0)
                        else:
                            mat.baseColorFactor = (0.8784, 0.8784, 0.8784, 1.0)
                    mat.roughnessFactor = 0.3
                    mat.metallicFactor = 0.2
                    #trm = trimesh.Trimesh(vertices = c_vets_array, faces = c_indices, process = False)
                    trm.apply_transform(pose)
                    #pr = pyrender.Primitive(trm.vertices, indices = trm.faces, mode = 4, \
# material = mat, normals = trm.vertex_normals)
                    primitives.append(pr)

            #if wireDis and len(wireDis) > 0:
            #    c_vets_array = []
            #    for v in wireDis:
            #        c_vets_array.append((v.x, v.y, v.z))
            #    mat = pyrender.MetallicRoughnessMaterial()
            #    mat.baseColorFactor = (0.5,0.5,0.5,1.0)
            #    pr = pyrender.Primitive(c_vets_array, mode = 1, material = mat, \
# poses = pose)
                #primitives.append(pr)
        elif hasattr(self.obj, 'Group'):
            for child in self.children:
                primitives.extend(child.renderPrimitive())
        return primitives

    def removeSameEdge(self):
        pass

